
using System;
using System.Data;
using System.Reflection;
using System.Collections.Generic;

namespace Serpis
{


	public class tableInfo
	{
		/*
		 * en principio lo he diseñado por separado, podría fuionarlo con persisterStorage,
		 * o en forma de estructura, aunque he decidido crear otro objeto para poderlo usar
		 * de forma comoda en el persister
		 * 
		 * se encarga de obtener los primary keys, y los fields para poder generar las consultas y
		 * parametros.
		 * */
		/*
		private static List<tableInfo> diccionario;
		private static tableInfo Instance;*/
		
		

		public Type type;
		private string table;
		private PropertyInfo primaryKey;
		private List<PropertyInfo> fields=new List<PropertyInfo>();
		
		
		public tableInfo(Type type){		
			this.type = type;
	        primaryKey=null;
			
			table = type.Name.ToLower();//necesito que sea Articulo y no PArticulo.Articulo

			foreach (PropertyInfo property in type.GetProperties())
			{
				if (property.IsDefined(typeof(PrimaryKeyAttribute),true))
				    primaryKey=property;
                else 
					if (property.IsDefined(typeof(FieldAttribute),true))
					{
						fields.Add(property);
					};
			}
                
		}
		
		public PropertyInfo PrimaryKey{
			get{return primaryKey;}
		}
		
		public List<PropertyInfo> Fields{
			get{return fields;}
		}
		
		public IDbCommand GetInsertCommand(object model){
				IDbCommand command=AppDbConnection.Instance.DbConnection.CreateCommand();
				
				foreach(PropertyInfo campos in fields)
					addPropiertyParameter(command, campos, model);
				
				command.CommandText= insertString();
				Console.WriteLine("haciendo insert");
				return command;
		}
		
		public IDbCommand GetUpdateCommand(object model){
				IDbCommand command=AppDbConnection.Instance.DbConnection.CreateCommand();
				
				addPropiertyParameter(command, primaryKey, model);
				foreach(PropertyInfo fila in fields)
					addPropiertyParameter(command, fila, model);
				
				command.CommandText= updateString();
				Console.WriteLine("haciendo update");
				return command;
		}
		
		public IDbCommand GetSelectCommand(int key){
			IDbCommand command = AppDbConnection.Instance.DbConnection.CreateCommand();
			
			command.addParameter(primaryKey.Name.ToLower(), key);
			
			command.CommandText = selectString();
			Console.WriteLine("haciendo select");
			return command;
		}
		
		public IDbCommand GetDeleteCommand(int key){
			IDbCommand command = AppDbConnection.Instance.DbConnection.CreateCommand();
			
			command.addParameter(primaryKey.Name.ToLower(), key);
			
			command.CommandText = deleteString();
			Console.WriteLine("haciendo delete");
			return command;
		}
		
		public string deleteString(){
			return String.Format("delete from articulo where {0}", table, primaryKey.Name.ToLower());
		}
		
		public string selectString(){			
			return String.Format("select * from {0} where {1}=?{1}", table, primaryKey.Name.ToLower());
		}
		
		
		public string insertString(){
			
			string sql="INSERT INTO "+table+"(";
			int i = 0;
			
			for(i=0; i<fields.Count - 1; i++)
				sql += fields[i].Name.ToLower()+", ";
			sql += fields[i].Name.ToLower();
			
			
            sql+=") VALUES (";
			
			for(i=0; i<fields.Count -1; i++)
				sql += "?"+fields[i].Name.ToLower()+", ";
			sql += fields[i].Name.ToLower();
			
            sql += ");";
			
            return sql;
		}
		
		private string updateString(){
			string sql="UPDATE "+table+" SET ";
			int i;
            for(i=0; i<fields.Count -1; i++)
            	sql+=fields[i].Name.ToLower()+"=?"+fields[i].Name.ToLower()+", ";
			sql+=fields[i].Name.ToLower()+"=?"+fields[i].Name.ToLower();
			
            sql+=" WHERE " + primaryKey.Name.ToLower()+"=?"+primaryKey.Name.ToLower();
			
			Console.WriteLine(sql);
			
            return sql;
				
		}
		
		private void addPropiertyParameter(IDbCommand command, PropertyInfo propiety, object model)
		{
			command.addParameter(propiety.Name.ToLower(), propiety.GetValue(model, null));
		}
	}
}
